package com.sgai.zero_robot.core.io;
import android.util.Log;
import com.sgai.zero_robot.utils.LogUtil;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.atomic.AtomicBoolean;

public class WriteHandler {
    private final String TAG = "WriteHandler";
    private LinkedBlockingDeque<byte[]> deque = new LinkedBlockingDeque<>();
    private OutputStream outputStream;
    private AtomicBoolean running = new AtomicBoolean(false);
    private Thread writerThread;
    private int PACKET_SIZE = 1024*3;
    public WriteHandler(OutputStream outputStream) {
        this.outputStream=outputStream;
    }
    private Runnable writerTask = new Runnable() {
        @Override
        public void run() {
            //只要socket处于连接的状态，就一直活动
            while (running.get()) {
                if (deque.size()>0){
                    try {
                        byte[] take = deque.take();
                        write(take);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else{
                    running.set(false);
                }
            }
        }
        private void write(byte[] msg) {
            Log.e(TAG, "write: "+new String(msg) );
            if (msg != null&&msg.length>0) {
                try {
                    int sumCount = msg.length;
                    ByteBuffer writeBuf = ByteBuffer.allocate(PACKET_SIZE); //分配一个内存缓存
//                writeBuf.order(ByteOrder.BIG_ENDIAN);
                    int currentCount = 0;
                    //如果要发送的数据大小大于每次发送的数据包的大小， 则要分多次将数据发出去
                    while (currentCount < sumCount) {
                        if (!running.get()){
                            return;
                        }
                        int realWriteLength = Math.min(PACKET_SIZE, sumCount);
                        writeBuf.clear(); //清空缓存
                        writeBuf.rewind(); //将position位置移到0
                        writeBuf.put(msg, currentCount, realWriteLength);
                        writeBuf.flip(); //将position赋为0，limit赋为数据大小
                        byte[] writeArr = new byte[realWriteLength];
                        writeBuf.get(writeArr);
                        outputStream.write(writeArr);
                        outputStream.flush(); //强制缓存中残留的数据写入清空
                        currentCount += realWriteLength;
                    }
                } catch ( IOException e) {
                    //写数据异常
                    e.printStackTrace();
                    LogUtil.e(e,Thread.currentThread());
                }
            }
        }
    };
    public void close() {
        Log.d(TAG, "closeWriter: "+running.get());
        if (running.get()){
            running.set(false);
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                LogUtil.e(e,Thread.currentThread());
            }
        }
    }

    private void openWriter() {
        Log.d(TAG, "openWriter: "+running.get());
        if (running.get()){
            return;
        }
        running.set(true);
        Log.d(TAG, "openWriter: 线程状态"+(writerThread!=null&&writerThread.isAlive()));
        if (writerThread!=null&&writerThread.isAlive()){
            return;
        }
        writerThread = new Thread(writerTask, "serial writer thread");
        writerThread.start();
    }
    public void sendMessage(byte[] bytes){
        if (bytes == null||bytes.length<=0){
            return;
        }
        Log.d(TAG, "sendMessage: msg="+new String(bytes));
        deque.add(bytes);
        openWriter();
    }
}
